.TITLE XMDRV .IDENT /04.1/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE ; AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS ; SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED ; OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO ; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ; DIGITAL EQUIPMENT CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY ; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. ; ; VERSION 04 ; ; DMC-11 DRIVER ; ; ; MPP005 -- ALLOW MODE CHANGE ONLY WHEN DEVICE ; IS OFFLINE ; ; RC006 -- GENERAL FIX UP FOR M V3.2 ; ; IZ004 -- CORRECT UMR DEALLOCATION ; ; RWS002 -- CORRECT SYSTEM CRASH BECAUSE NO I/O PACKET ON QUEUE AFTER ; IOKILL OR LINE GOING DOWN SPR11-60550 .SBTTL LIBRARY MACROS ;JFR002 .MCALL CUCDF$,INTSV$,PKTDF$,SCBDF$,UCBDF$ CUCDF$ ;COMMUNICATIONS UCB DEFINITIONS PKTDF$ ;I/O PACKET DEFINITIONS SCBDF$ ;SCB DEFINITIONS UCBDF$ ;UCB DEFINITIONS .SBTTL CONDITIONAL ASSEMBLY PARAMETERS ; 22 BIT ADDRESSING .IIF DF M$$MGE & M$$EXT, X$$22=0 ; 18 BIT ADDRESSING .IF DF M$$MGE .IIF NDF M$$EXT, X$$18=0 .ENDC ; QIO DRIVER PLUS 22 BIT ADDRESSING .IIF DF X$$22 Q$$22=0 X$$M11=X$$M11 ; DON'T LAUGH ; LOADABLE DRIVER MAPPING NEEDED .IIF DF M$$MGE & LD$XM, X$$LDM=0 ; DYNAMIC UMR ALLOCATION COUNT .IF DF R$$MPL!V$$RSN&Q$$22 .IIF NDF XM$UMR, XM$UMR=5 .IIF NE XM$UMR-3, XM$UMR=5 .ENDC .SBTTL EQUATED SYMBOLS ; BIT ASSIGNMENTS BIT0=1 BIT1=2 BIT2=4 BIT3=10 BIT4=20 BIT5=40 BIT6=100 BIT7=200 BIT8=400 BIT9=1000 BIT10=2000 BIT11=4000 BIT12=10000 BIT13=20000 BIT14=40000 BIT15=100000 ; CSR INDEX VALUES SEL0=0 SEL2=2 ; SEL0 ASSIGNMENTS RUN=BIT15 ;RUN MC=BIT14 ;MASTER CLEAR RDYI=BIT7 ;MICROPROCESSOR READY FOR INPUT IEI=BIT6 ;INPUT INTERRUPT ENABLE RQI=BIT5 ;REQUEST IN TYPE=BIT2!BIT1!BIT0 ;REQUEST TYPE RELEAS=RQI!IEI ;PORT RELEASE ; SEL0 INPUT TRANSACTION TYPES BACCI=RQI ;BUFFER ADDRESS/CHARACTER COUNT IN CNTLI=RQI!BIT0 ;CONTROL IN BASEI=RQI!BIT1!BIT0 ;BASE IN XMT=BACCI ;TRANSMIT BUFFER RCV=BACCI!BIT2 ;RECEIVE BUFFER PERR=BASEI ;CAUSE PROCEDURE ERROR BY DOING BASE IN TWICE ; SEL2 ASSIGNMENTS RDYO=BIT7 ;MICROPROCESSOR READY FOR OUTPUT IEO=BIT6 ;OUTPUT INTERRUPT ENABLE ; SEL6 ASSIGNMENTS (CNTLI) HDX=BIT10 ;HALF DUPLEX SCNDRY=BIT11 ;HALF DUPLEX SECONDARY STATION MOP=BIT8 ;MAINTENANCE MODE ; SEL6 ASSIGNMENTS (BASEI) RESUME=BIT12 ;RESUME AFTER POWERFAIL (PERIPHERALS HANDBOOK IS WRONG!) ; SEL6 ASSIGNMENTS (CNTLO) DATACK=BIT0 ;RETRANSMISSION THRESHOLD EXCEEDED TIMOUT=BIT1 ;NO REMOTE RESPONSE FOR 21 SECONDS ORUN=BIT2 ;MESSAGE RECEIVED BUT NO BUFFER AVAILABLE MAINT=BIT3 ;DDCMP MAINTENANCE RECEIVED LOST=BIT4 ;MESSAGE RECEIVED > BUFFER SIZE DISCON=BIT6 ;MODEM DATA SET READY LEAD WENT FROM ON TO OFF START=BIT7 ;DDCMP START RECEIVED MEMORY=BIT8 ;UNIBUS TIME-OUT ON MEMORY REFERENCE BUG=BIT9 ;PROGRAM BUG! UNXINT=BIT14 ;UNEXPECTED INTERRUPT, NO I/O PACKET AVAILABLE FATAL=TIMOUT!MAINT!LOST!START!MEMORY!BUG ; U.CW3 ASSIGNMENTS U3.ERR=BIT15 ;HAS FATAL ERROR OCCURRED? (1=YES) U3.KIL=BIT14 ;HAS I/O KILL BEEN DONE? (1=YES) U3.PWF=BIT13 ;HAS POWER FAILED? (1=YES) U3.MOD=HDX!SCNDRY!MOP ;CURRENT OPERATING MODE U3.FRK=BIT0 ;IS FORK PROCESS RUNNING? (1=YES) ; UCB DISPLACEMENTS USED .ASECT .=U.VCB+2 U.XQ: .BLKW 1 ;TRANSMIT LISTHEAD ADDRESS U.RQ: .BLKW 1 ;RECEIVE LISTHEAD ADDRESS U.ERR: .BLKW 1 ;ERROR STATUS U.LEN=. .PSECT ; MAXIMUM NUMBER OF BUFFERS WHICH DMC CAN HANDLE .IF DF Q$$22 .IF DF V$$RSN!R$$MPL .IIF EQ XM$UMR-3, MAXBUF=1 .ENDC .IIF NDF MAXBUF, MAXBUF=2 .ENDC .IIF NDF MAXBUF, MAXBUF=7 ; LISTHEAD DISPLACEMENTS .ASECT .=0 .BLKW 2 ;SENT QUEUE .BLKW 2 ;WAIT QUEUE IOTYPE: .BLKB 1 ;SEL0 REQUEST TYPE COUNT: .BLKB 1 ;SENT COUNT .IF DF Q$$22 UMR: .BLKW 1 ;NEXT UMR TO USE UMRSUM: .BLKW 1 ;SUM OF BOTH UMR ADDRESSES .ENDC .PSECT ; FIRST UMR ADDRESS FIRSTUMR=170200 ; WHERE BUFFER ADDRESS AND COUNT ARE TO BE FOUND X.PRM=I.PRM ; DEVICE INITIALIZATION WAIT TIMES S.WAIT=200. ;LOOP COUNTDOWN VALUE WAITING FOR RDYI TO BE SET C.WAIT=100. ;DITTO WAITING FOR RDYI TO BE CLEARED .SBTTL LOCAL DATA ; MICROPROCESSOR BASE TABLE(S) ; *** WARNING *** THIS MUST BE THE FIRST ASSEMBLY LOCATION BASE: .REPT X$$M11 .BLKW 128. .ENDR ; DRIVER DISPATCH TABLE .IF DF R$$MPL DDT$ XM,X$$M11,,INIT,CNTBL,NEW .IFF DDT$ XM,X$$M11,,INIT,CNTBL .ENDC ; TEMPORARY UNIT SAVE .IF GT X$$M11-1 TEMP: .BLKW 1 .ENDC ; LISTHEADS LIST: .REPT X$$M11 .WORD 0,.-2 ;COMPLETED BUFFERS .WORD 0,.-2 ;TRANSMITS SENT (U.XQ) .WORD 0,.-2 ;TRANSMITS WAITING .BYTE XMT,0 .IF DF Q$$22 .BLKW 2 .IFTF .WORD 0,.-2 ;RECEIVES SENT (U.RQ) .WORD 0,.-2 ;RECEIVES WAITING .BYTE RCV,0 .IFT .BLKW 2 .ENDC .ENDR ; MULTIPLE UNIT BASE TABLE ADDRESSES .IF NDF X$$LDM .IF GT X$$M11-1 BTAB: BADDR=BASE .REPT X$$M11 .WORD BADDR BADDR=BADDR+256. .ENDR .ENDC .ENDC ; MULTIPLE UNIT LISTHEAD ADDRESSES .IF GT X$$M11-1 XLTAB: XLADDR=LIST+4 .REPT X$$M11 .WORD XLADDR .IF DF Q$$22 XLADDR=XLADDR+32. .IFF XLADDR=XLADDR+24. .ENDC .ENDR .ENDC ; ADDRESS EXTENSION BITS .IF DF M$$MGE AXTAB: .WORD 0,40000,100000,140000 .ENDC .SBTTL INITIATE I/O ;+ ; **-XMINIT-INITIATE DMC I/O ; ; INPUTS: ; R5=UCB ADDRESS ; ; OUTPUTS: ; ALL I/O PACKETS PROCESSED ; ; NOTE: ; IF TIMER IS ACTIVE, DISCONNECT ERROR RECOVERY IS IN PROGRESS ;- XMRET: RETURN XMINIT: MOV U.SCB(R5),R4 ;SCB ADDRESS TSTB S.CTM(R4) ;IS TIMER ACTIVE? BNE XMRET ;IF NE, YES - MUST WAIT MOVB S.STS(R4),-(SP) ;SAVE ACTIVITY COUNT CLRB S.STS(R4) ;DECLARE CONTROLLER NOT BUSY BICB #US.BSY,U.STS(R5) ; AND IDLE THE UNIT CALL $GTPKT ;GET AN I/O PACKET IF AVAILABLE MOVB (SP)+,S.STS(R4) ;RESTORE ACTIVITY COUNT BCS XMRET ;IF CS, NO MORE PACKETS ; ; $GTPKT RETURNS THE FOLLOWING: ; R1=I/O PACKET ADDRESS ; R2=PHYSICAL UNIT NUMBER (U.UNIT) ; R3=CONTROLLER INDEX (S.CON) ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; MOV R5,R2 ;UCB ADDRESS ADD #U.CW2,R2 ;U.CW2 ADDRESS CMPB #IO.INL/256.,I.FCN+1(R1);IS IT A TRANSFER FUNCTION? BLOS 2$ ;IF LOS, NO JMP TRAN ;ELSE IT IS A TRANSFER REQUEST ; ; CONTROL FUNCTION ; 2$: BNE 20$ ;IF NE, MODE CHANGE REQUEST TSTB I.FCN(R1) ;IS IT TERMINATE FUNCTION? BNE 10$ ;IF NE, YES ; ; INITIALIZE (IO.INL) ; BIT #U2.ONL,(R2) ;IS DEVICE ALREADY ON-LINE? BNE PKTOK ;IF NE, YES MOV R5,CNTBL(R3) ;SAVE UCB ADDRESS .IF GT X$$M11-1 MOV XLTAB(R3),R0 ;TRANSMIT LISTHEAD ADDRESS .IFF MOV #LIST+4,R0 ;TRANSMIT LISTHEAD ADDRESS .ENDC MOV R0,U.XQ(R5) ;SAVE TRANSMIT LISTHEAD ADDRESS ADD #COUNT,R0 ;POINT TO SENT COUNT CLRB (R0)+ ;ZERO IT OUT .IF DF Q$$22 .IF DF V$$RSN!R$$MPL .IF NDF R$$MPL TST S.MPR+2(R4) ;DOES UMR BLOCK ALREADY EXIST? .IFF MOV S.KRB(R4),R2 ; MOV KRB ADDRESS INTO R2 ADD K.OFF(R2),R2 ;POINT TO UMR AREA + 2 SUB #M.LGTH,R2 ;POINT TO START OF UMR AREA TST (R2) ; IS IT ALREADY SET UP? .ENDC BNE 6$ ;IF NE, YES (!!!) MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ;AND THE PACKET ADDRESS MOV R2,-(SP) ;AND SAVE R2 MOV #M.LGTH,R1 ;SET SIZE OF BLOCK TO BE REQUESTED CALL $ALOCB ;TRY TO ALLOCATE THE DATA BLOCK BCS 4$ ;IF C-SET WE FAILED MOV #,M.UMRN(R0) ;SETUP UMR COUNT * 4 CALL $ASUMR ;TRY TO GET THE UMRS BCC 5$ ;IF C-CLEAR WE GOT THEM CALL $DEACB ;ELSE GIVE BACK THE DATA BLOCK 4$: MOV (SP)+,R2 ;RESTORE R2 MOV (SP)+,R1 ;AND PACKET ADDRESS TST (SP)+ ;POP THE STACK BR XMRSU ;AND REPORT THE RESOURCE ALLOCATION FAILURE 5$: MOV (SP)+,R2 ;RESTORE R2 .IF NDF R$$MPL MOV M.UMRA(R0),S.MPR(R4) ;SAVE FIRST UMR MOV R0,S.MPR+2(R4) ;AND THE UMR BLOCK ADDRESS .IFF MOV M.UMRA(R0),(R2) ;SAVE FIRST UMR MOV R0,2(R2) ; AND THE UMR BLOCK ADDRESS .ENDC MOV R5,M.UMVL(R0) ;MARK THE UMR BLOCK (FOR SYSTEM DEBUGGING) MOV (SP)+,R1 ;RESTORE THE PACKET ADDRESS MOV (SP)+,R0 ;AND THE LISTHEAD POINTER .ENDC .IF NDF R$$MPL 6$: MOV S.MPR(R4),R2 ;FIRST UMR IS FOR BASE TABLE .IFF 6$: MOV S.KRB(R4),R2 ; MOV KRB ADDRESS INTO R2 ADD K.OFF(R2),R2 ;POINT TO UMR AREA + 2 SUB #M.LGTH,R2 ;POINT TO START OF UMR AREA MOV (R2),R2 ;R2=FIRST UMR FOR BASE TABLE .ENDC CMP (R2)+,(R2)+ ;SECOND AND THIRD UMRS ARE FOR TRANSMITS MOV R2,(R0)+ ;SECOND UMR ADDRESS MOV R2,(R0) .IF EQ MAXBUF-2 CMP (R2)+,(R2)+ ;GET TO THE THIRD UMR .ENDC ADD R2,(R0)+ ;SUM OF SECOND AND THIRD UMR ADDRESSES .IFTF MOV R0,U.RQ(R5) ;SAVE RECEIVE LISTHEAD ADDRESS .IFT ADD #COUNT,R0 ;POINT TO SENT COUNT CLRB (R0)+ ;ZERO IT OUT CMP (R2)+,(R2)+ ;FOURTH AND FIFTH UMRS ARE FOR RECEIVES MOV R2,(R0)+ ;FOURTH UMR ADDRESS MOV R2,(R0) .IF EQ MAXBUF-2 CMP (R2)+,(R2)+ ;GET TO THE FIFTH UMR .ENDC ADD R2,(R0) ;SUM OF FOURTH AND FIFTH UMR ADDRESSES .IFF CLRB COUNT(R0) ;ZERO OUT RECEIVE SENT COUNT .ENDC CALL SETDMC ;INITIALIZE DMC HARDWARE BCS XMINF ;IF CS, HARDWARE TROUBLE BIS #U2.ONL,U.CW2(R5) ;SET ON-LINE BIT BIC #^C,U.CW3(R5) ;CLEAR EVERYTHING EXCEPT MODE BR PKTOK ;RETURN SUCCESSFUL STATUS ; ; TERMINATE (IO.TRM) ; 10$: MOV R1,-(SP) ;SAVE PACKET ADDRESS CLR R0 ;NO SPECIAL ERROR CODE CALL KILL ;KILL THE DEVICE 16$: MOV (SP)+,R1 ;RESTORE THE PACKET ADDRESS BR PKTOK ;RETURN SUCCESSFUL STATUS ; ; MODE CHANGE FUNCTION ; 20$: BIT #U2.ONL,(R2) ;IS DEVICE ON-LINE? BNE XMDNR ;IF NE, YES BITB #IO.HDX,I.FCN(R1);IS SUB-FUNCTION HALF-DUPLEX? BNE 30$ ;IF NE, YES BITB #IO.FDX,I.FCN(R1);IS SUB-FUNCTION FULL DUPLEX? BEQ XMIFC ;IF EQ, NO ; ; FULL DUPLEX (IO.FDX) ; BIT #U2.LIN,(R2) ;WAS DEVICE SYSGENED AS HALF-DUPLEX? BNE XMIFC ;IF NE, YES BIC #U2.HDX,(R2)+ ;SET FULL DUPLEX IN U.CW2 CLR (R2) ;HALF-DUPLEX MODE BIT OFF BR 50$ ; ; HALF-DUPLEX (IO.HDX) ; 30$: BIS #U2.HDX,(R2)+ ;SET HALF-DUPLEX IN U.CW2 MOV #HDX,(R2) ;HALF-DUPLEX MODE BIT TST I.PRM(R1) ;LOOK AT QIO PARAMETER P1 BEQ 40$ ;IF EQ, PRIMARY STATION BIS #SCNDRY,(R2) ;IF NE, SECONDARY STATION 40$: TST I.PRM+2(R1) ;LOOK AT QIO PARAMETER P2 BEQ 50$ ;IF EQ, NORMAL MODE BIS #MOP,(R2) ;IF NE, MAINTENANCE MODE 50$: ;FALL THRU TO PKTOK .SBTTL FINISH I/O PACKET ;+ ; **-PKTOK-FINISH PACKET WITH STATUS OF "IS.SUC" ; **-FINPKT-ALTERNATE ENTRY ; ; INPUTS: ; R1=I/O PACKET ADDRESS ; R5=UCB ADDRESS ; ; CALLING SEQUENCE: ; JMP PKTOK ; ; OUTPUTS: ; PACKET FINISHED ; XMINIT CALLED TO START ANY NEW PACKETS ;- PKTOK: MOV #IS.SUC&377,-(SP);SUCCESSFUL STATUS FINPKT: MOV R1,-(SP) ;SAVE PACKET ADDRESS CALL XMINIT ;TRY ANOTHER PACKET MOV (SP)+,R3 ;RESTORE PACKET ADDRESS MOV (SP)+,R0 ;STATUS WORD 1 CLR R1 ;STATUS WORD 2 = 0 CALLR $IOFIN ;FINISH I/O PACKET ; ; DEVICE NOT READY ; XMINF: .IF DF R$$MPL!V$$RSN&Q$$22 CALL DEUMR ;DE-ALLOCATE UMR'S .ENDC XMDNR: MOV #IE.DNR&377,-(SP) BR FINPKT ; ; ILLEGAL BUFFER ; XMSPC: MOV #IE.SPC&377,-(SP) BR FINPKT ; ; ILLEGAL FUNCTION CODE ; XMIFC: MOV #IE.IFC&377,-(SP) BR FINPKT ; ; RESOURCE ALLOCATION FAILURE ; .IF DF R$$MPL!V$$RSN&Q$$22 XMRSU: MOV #IE.RSU&377,-(SP) BR FINPKT .ENDC .SBTTL PROCESS QIO TRANSFER FUNCTION ; ; TRANSFER FUNCTION ; TRAN: BIT #U2.ONL,(R2) ;IS DEVICE ON-LINE? BEQ XMDNR ;IF EQ, NO .IF DF X$$22 BIT #160000,I.PRM+4(R1) ;IS BUFFER SIZE >= 4K WORDS? ;BUFFER MUST BE MAPPED BY 1 UMR .IFF BIT #140000,I.PRM+4(R1) ;IS BUFFER SIZE >= 8K WORDS? .ENDC BNE XMSPC ;IF NE, YES - BUFFER IS TOO BIG INCB S.STS(R4) ;INCR ACTIVITY COUNT .IF DF X$$18 MOV I.PRM(R1),R0 ;GET NPR EXTENSION BITS SWAB R0 ;AND SHIFT FROM BIT POSITIONS 5-4 ASL R0 ;TO BIT POSITIONS 15-14 ASL R0 BIS R0,I.PRM+4(R1) ;THEN AND WITH BYTE COUNT .ENDC CMPB #IO.WLB/256.,I.FCN+1(R1) ;IS IT A WRITE FUNCTION? BEQ 10$ ;IF EQ, YES ; ; RECEIVE DATA (IO.RLB OR IO.RNS) ; MOV U.RQ(R5),R0 ;RECEIVE LISTHEAD ADDRESS BR 20$ ; ; TRANSMIT DATA (IO.WLB OR IO.WNS) ; 10$: MOV U.XQ(R5),R0 ;TRANSMIT LISTHEAD ADDRESS 20$: MOV #XMINIT,-(SP) ;SET TO RETURN TO XMINIT ;FALL THRU TO TRY .SBTTL TRY TO GIVE TRANSFER REQUEST TO DMC ;+ ; **-TRY-TRY TO GIVE TRANSFER REQUEST TO DMC ; ; INPUTS: ; R0=SENT Q LISTHEAD ADDRESS (U.XQ OR U.RQ) ; R1=I/O PACKET ADDRESS ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS IF PORT WAS NOT AVAILABLE: ; R0=WAIT Q LISTHEAD ADDRESS ; R2,R3=DESTROYED ; R4=CSR ADDRESS ; PACKET QUEUED ON WAIT Q ; ; OUTPUTS IF PORT WAS AVAILABLE BUT NOT READY: ; R0=WAIT Q LISTHEAD ADDRESS ; R2,R3=DESTROYED ; R4=CSR ADDRESS ; REQUEST TYPE!IEI LEFT IN SEL0 ; PACKET QUEUED ON WAIT Q ; ; OUTPUTS IF PORT WAS AVAILABLE AND READY: ; R2,R3=DESTROYED ; R4=CSR ADDRESS ; DMC GIVEN BUFFER ADDRESS AND COUNT ; DMC PORT RELEASED ; SENT COUNT INCREMENTED ; PACKET QUEUED ON SENT Q ;- TRY: MTPS S.PRI(R4) ;DISABLE INTERRUPTS MOV S.CSR(R4),R4 ;;;CSR ADDRESS TST 4(R0) ;;;IS WAIT Q EMPTY? BNE 30$ ;;;IF NE, NO - NO ACTION POSSIBLE CALL PORT ;;;IS PORT AVAILABLE? BCS 30$ ;;;IF CS, NO BIT #RDYO,2(R4) ;;;IS OUTPUT TRANSFER READY? BNE 20$ ;;;IF NE, YES - USE INTERRUPTS MOV #4,R2 ;;;LOOP COUNT 10$: BIT #RDYI,(R4) ;;;IS DMC READY FOR INPUT? BNE 40$ ;;;IF NE, YES SOB R2,10$ ;;; 20$: BIS #IEI,(R4) ;;;ENABLE INPUT INTERRUPT BIS #IEI,(R4) ;;;TWICE 30$: CMP (R0)+,(R0)+ ;;;WAIT Q LISTHEAD ADDRESS CALL $QINSF ;;;INSERT PACKET ON WAIT Q ;;;NOTE-$QINSF DESTROYS R2 BR 50$ ;;; 40$: CALL GIVE ;;;GIVE PACKET INFO TO DMC 50$: MTPS #0 ;;;RE-ENABLE INTERRUPTS RETURN .SBTTL LOAD DATA PORT WITH BUFFER ADDRESS AND COUNT ;+ ; **-GIVE-GIVE BUFFER ADDRESS AND COUNT TO DMC ; ; INPUTS: ; R0=SENT Q LISTHEAD ADDRESS ; R1=I/O PACKET ADDRESS ; R4=CSR ADDRESS ; DMC READY FOR INPUT ; ; OUTPUTS: ; R2,R3=DESTROYED ; DMC GIVEN BUFFER ADDRESS AND COUNT ; DMC PORT RELEASED ; SENT COUNT INCREMENTED ; PACKET INSERTED ON SENT Q ;- GIVE: INCB COUNT(R0) ;;;INCREMENT SENT COUNT .IF DF Q$$22 MOV R0,R2 ;;;COPY LISTHEAD ADDRESS MOV UMR(R2),R0 ;;;NEXT UMR TO USE MOV UMRSUM(R2),UMR(R2) ;;;RESET NEXT UMR ADDRESS SUB R0,UMR(R2) ;;; MOV R2,-(SP) ;;;SAVE LISTHEAD ADDRESS MOV X.PRM(R1),R2 ;;;PUT 18 BIT ADDRESS IN R2,R3 SWAB R2 ;;; MOV X.PRM+2(R1),R3 ;;; CALL MAP22 ;;;DO 22 BIT MAPPING AND LOAD DATA PORT BIS X.PRM+4(R1),6(R4) ;;;INCLUDE BYTE COUNT MOV (SP)+,R0 ;;;RESTORE LISTHEAD ADDRESS .IFF MOV X.PRM+2(R1),4(R4) ;;;GIVE DMC BUFFER ADDRESS MOV X.PRM+4(R1),6(R4) ;;;AND COUNT .ENDC BIC #RELEAS,(R4) ;;;RELEASE THE PORT CALLR $QINSF ;;;INSERT PACKET ON SENT Q ;;;NOTE-$QINSF DESTROYS R2 .SBTTL INITIALIZE DMC HARDWARE ;+ ; **-SETDMC-INITIALIZE DMC HARDWARE ; ; INPUTS: ; R3=CONTROLLER INDEX (S.CON) ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; U3.MOD=DMC MODE ; ; OUTPUTS: ; R0,R2,R3=DESTROYED ; R4=CSR ADDRESS ; CARRY CLEAR=OK ; CARRY SET=HARDWARE NOT WORKING PROPERLY ;- .ENABL LSB SETDMC: CLR U.ERR(R5) ;CLEAR ERROR STATUS AND C-BIT .IF DF X$$22 .IF NDF R$$MPL MOV S.MPR(R4),R0 ;GET THE BASE TABLE UMR .IFF MOV S.KRB(R4),R0 ; MOV KRB ADDRESS INTO R0 ADD K.OFF(R0),R0 ;POINT TO UMR AREA + 2 SUB #M.LGTH,R0 ;POINT TO START OF UMR AREA MOV (R0),R0 ;GET BASE TABLE UMR .ENDC .ENDC MOV S.CSR(R4),R4 ;CSR ADDRESS BIS #MC,(R4) ;MASTER CLEAR THE DMC ; THE FOLLOWING INSTRUCTION NEEDED WITH COMIOP BOARD AND OK WITHOUT MOV #RUN,(R4) ;START THE MICROPROCESSOR BIS #IEO,2(R4) ;ENABLE COMPLETION INTERRUPTS MOVB #BASEI,(R4) ;BASE IN REQUEST TYPE CALL WRDYIS ;WAIT FOR RDYI SET BCS 40$ ;IF CS, TROUBLE ; ; THE BASE TABLE ADDRESS IS CALCULATED AS FOLLOWS: ; IF UNMAPPED, USE EITHER "#BASE" OR "BTAB(R3)". ; IF MAPPED AND DMC DRIVER IS NOT LOADABLE, SAME AS UNMAPPED. ; IF MAPPED AND DMC DRIVER IS LOADABLE, USE KISAR5 CONTENTS ; SHIFTED LEFT 6 PLACES. ; ; THUS, THE UMR IS ALWAYS SET TO THE ADDRESS OF THE FIRST ; BASE TABLE AND THE 18 BIT ADDRESS IS ADJUSTED ACCORDINGLY. ; .IF DF X$$LDM CLR R2 ;NO EXTENSION BITS YET .IF DF X$$22 ASR R3 ;CALCULATE UNIT # * 400 SWAB R3 MOV R3,-(SP) ;SAVE IT ON STACK MOV KISAR5,R3 ;UMR ALWAYS POINTS TO FIRST BASE TABLE .IFF ASL R3 ;BASE TABLE DISPLACEMENT/100 ADD KISAR5,R3 ;PLUS DRIVER ADDRESS/100 .IFTF MOV #6,-(SP) ;NOW MULTIPLY BY 100 5$: ASL R3 ;BY SHIFTING R2,R3 LEFT ROL R2 ;6 PLACES DEC (SP) ;DONE? BNE 5$ ;IF NE, NO TST (SP)+ ;PURGE LOOP COUNT .IFT CALL MAP22 ;DO 22 BIT MAPPING AND LOAD DATA PORT ADD (SP)+,4(R4) ;ADJUST BY MULTIPLE BASE TABLE INDEX .IFF MOV R3,4(R4) ;LOW 16 BITS OF ADDRESS ASL R2 ;MAKE A WORD INDEX MOV AXTAB(R2),6(R4) ;ADDRESS EXTENSION BITS .ENDC .IFF .IF GT X$$M11-1 MOV BTAB(R3),4(R4) ;LOW 16 BITS OF ADDRESS .IFF MOV #BASE,4(R4) ;LOW 16 BITS OF ADDRESS .ENDC CLR 6(R4) ;NO EXTENSION BITS .ENDC CALL WRDYIC ;RELEASE PORT AND WAIT FOR RDYI CLEAR BCS 40$ ;IF CS, TROUBLE MOVB #CNTLI,(R4) ;CONTROL IN REQUEST TYPE CALL WRDYIS ;WAIT FOR RDYI SET BCS 40$ ;IF CS, TROUBLE MOV U.CW3(R5),-(SP) ;STRIP MODE BITS FROM U.CW3 BIC #^C,(SP) MOV (SP)+,6(R4) ;SET DMC MODE ;FALL THRU TO WRDYIC ; ; RELEASE PORT AND WAIT FOR RDYI CLEAR ; WRDYIC: BIC #RELEAS,(R4) ;RELEASE THE PORT MOV #C.WAIT,R2 ;LOOP COUNT 10$: BIT #RDYI,(R4) ;IS RDYI STILL SET? BEQ 40$ ;IF EQ, NO SOB R2,10$ BR 30$ ;RDYI NOT CLEARED PROPERLY ; ; WAIT FOR RDYI SET ; WRDYIS: MOV #S.WAIT,R2 ;LOOP COUNT 20$: BIT #RDYI,(R4) ;IS RDYI SET? BNE 40$ ;IF NE, YES SOB R2,20$ 30$: SEC ;RDYI NOT SET PROPERLY 40$: RETURN .DSABL LSB .SBTTL DO 22 BIT MAPPING ;+ ; **-MAP22-DO 22 BIT MAPPING AND LOAD DATA PORT ; ; INPUTS: ; R0=UMR ADDRESS ; R2,R3=22 BIT PHYSICAL ADDRESS ; R4=CSR ADDRESS ; ; OUTPUTS: ; R0,R2,R3=DESTROYED ; UMR LOADED WITH PHYSICAL ADDRESS ; DATA PORT LOADED WITH 18 BIT UMR ADDRESS ;- .IF DF X$$22 MAP22: MOV R3,(R0) ;COPY R2,R3 TO UMR BIC #1,(R0)+ ;FIRST WORD OF UMR MUST BE EVEN MOV R2,(R0)+ SUB #FIRSTU+4,R0 ;UMR# IS NOW IN BITS 6-2 SWAB R0 ASL R0 CLR R2 ;FORM AN 18 BIT NUMBER IN R2,R0 ASL R0 ;WITH BITS 17-13 CONTAINING THE UMR# ROL R2 ASL R0 ROL R2 ROR R3 ;ODD/EVEN BIT TO CARRY ADC R0 ;AND THEN TO BIT 0 OF ADDRESS MOV R0,4(R4) ;LOW 16 BITS OF ADDRESS TO DATA PORT ASL R2 ;MAKE A WORD INDEX MOV AXTAB(R2),6(R4) ;ADDRESS EXTENSION BITS TO DATA PORT RETURN .ENDC .SBTTL PROCESS RDYI INTERRUPT ; ; PROCESS RDYI INTERRUPT ; $XMINP::INTSV$ XM,PR5,X$$M11,,CNTBL ;;;GENERATE INTERRUPT SAVE CODE JSR R0,XMSET ;;;DO INTERRUPT SETUP AND TRANSFER .WORD SEL0 ;;;CSR INDEX .WORD XMTRDY ;;;TRANSFER ADDRESSES .WORD BAD .WORD BAD .WORD FPERR .WORD RCVRDY .WORD BAD .WORD BAD .WORD BAD ; ; DMC READY FOR TRANSMIT BUFFER ; XMTRDY: MOV U.XQ(R5),R0 ;;;TRANSMIT LISTHEAD ADDRESS JSR R1,RDYINT ;;;GIVE BUFFER TO DMC ; ; DMC READY FOR RECEIVE BUFFER ; RCVRDY: MOV U.RQ(R5),R0 ;;;RECEIVE LISTHEAD ADDRESS JSR R1,RDYINT ;;;GIVE BUFFER TO DMC ; ; FORCE PROCEDURE ERROR ; FPERR: BIC #RELEAS,(R4) ;;;CLEAR RQI WHICH WILL CAUSE BR XMINTX ;;;CNTLO INTERRUPT .SBTTL PROCESS COMPLETION OR CONTROL OUT INTERRUPT ; ; PROCESS COMPLETION INTERRUPT ; $XMOUT::INTSV$ XM,PR5,X$$M11,,CNTBL ;;;GENERATE INTERRUPT SAVE CODE JSR R0,XMSET ;;;DO INTERRUPT SETUP AND TRANSFER .WORD SEL2 ;;;CSR INDEX .WORD XMTCOM ;;;TRANSFER ADDRESSES .WORD CNTLO .WORD BAD .WORD BAD .WORD RCVCOM .WORD CNTLO .WORD BAD .WORD BAD ; ; TRANSMIT BUFFER COMPLETE ; XMTCOM: MOV U.XQ(R5),R0 ;;;TRANSMIT LISTHEAD ADDRESS JSR R1,BUFCOM ;;;PROCESS BUFFER COMPLETE ; ; RECEIVE BUFFER COMPLETE ; RCVCOM: MOV U.RQ(R5),R0 ;;;RECEIVE LISTHEAD ADDRESS JSR R1,BUFCOM ;;;PROCESS BUFFER COMPLETE ; ; CONTROL OUT ; CNTLO: MOV 4(R4),R0 ;;;COPY SEL6 CONTENTS BIC #RDYO,(R4) ;;;RELEASE THE PORT BIS R0,U.ERR(R5) ;;;UPDATE ERROR STATUS BIT #FATAL,R0 ;;;IS IT A FATAL ERROR? BEQ 20$ ;;;IF EQ, NO BIT #BUG,R0 ;;;IS IT DISCONNECT ERROR PART 2? BEQ 10$ ;;;IF EQ, NO MOV U.SCB(R5),R4 ;;;SCB ADDRESS MOVB #2,S.CTM(R4) ;;;SET TIMER FOR BETWEEN 1 AND 2 SECONDS ;;;NOTE-ONLY 1 SECOND DELAY IS NEEDED BR XMFRK ;;;CAN'T MASTER CLEAR UNTIL THEN 10$: BIS #MC,-(R4) ;;;MASTER CLEAR THE DMC BR XMFRK ;;;START FORK PROCESS 20$: BIT #DISCON,R0 ;;;IS IT DISCONNECT ERROR? BEQ XMINTX ;;;IF EQ, NO MOVB #PERR!IEI,-2(R4);;;CAUSE PROCEDURE ERROR ;;;FALL THRU TO XMINTX ; ; EXIT FROM INTERRUPT ; BAD: XMINTX: MOV (SP)+,R0 ;;;RESTORE R0 JMP $INTXT ;;;EXIT FROM INTERRUPT .SBTTL SETUP FOR INTERRUPT ROUTINES AND TRANSFER ;+ ; **-XMSET-SETUP FOR INTERRUPT ROUTINES AND TRANSFER ; ; INPUTS: ; R0=CALLING REGISTER ; INTSV$ HAS BEEN DONE ; ; CALLING SEQUENCE: ; JSR R0,XMSET ; .WORD ;;;CSR INDEX (EITHER 0 OR 2) ; .BLKW 8. ;;;TRANSFER ADDRESSES BY TYPE ; ; OUTPUTS: (IF VALID INTERRUPT) ; R4=CSR ADDRESS ; R5=UCB ADDRESS ; (SP)=SAVED R0 ; ; ALTERNATE RETURN: (IF INVALID INTERRUPT) ; RETURN TO $INTXT ;- XMSET: TST R5 ;;;HAS UCB BEEN ENTERED IN TABLE? BEQ XMINTX ;;;IF EQ, NO BIT #U2.ONL,U.CW2(R5);;;IS DMC ON-LINE? BEQ XMINTX ;;;IF EQ, NO MOV U.SCB(R5),R4 ;;;SCB ADDRESS MOV S.CSR(R4),R4 ;;;CSR ADDRESS ADD (R0)+,R4 ;;;PLUS CSR INDEX MOV (R4),-(SP) ;;;STRIP EVERYTHING BUT TYPE BITS BIC #^C,(SP) ASL (SP) ;;;MAKE A WORD INDEX ADD (SP)+,R0 ;;;ADD TO TRANSFER TABLE ADDRESS JMP @(R0)+ ;;;AND GO! .SBTTL RDYI INTERRUPT ROUTINES ;+ ; **-RDYINT-GIVE BUFFER TO DMC ; ; INPUTS: ; R0=SENT Q LISTHEAD ADDRESS (U.XQ OR U.RQ) ; R1=CALLING REGISTER ; R4=CSR ADDRESS ; R5=UCB ADDRESS ; 2(SP)=INTERRUPT SAVED R0 ; ; CALLING SEQUENCE: ; JSR R1,RDYINT ; ; OUTPUTS: ; DMC GIVEN BUFFER ADDRESS AND COUNT ; DMC PORT RELEASED ; ATTEMPT MADE TO SETUP ANOTHER BUFFER OF EITHER TYPE ; INTERRUPT EXITED ;- RDYINT: MOV R2,-(SP) ;;;SAVE R2,R3 MOV R3,-(SP) ;;; CMP (R0)+,(R0)+ ;;;ADVANCE TO WAIT Q ADDRESS CALL $QRMVF ;;;REMOVE FIRST PACKET FROM WAIT Q ;;;NOTE-$QRMVF DESTROYS R2,R3 BCS 20$ ;;;NO PACKET ON QUEUE IF CARRY SET CMP -(R0),-(R0) ;;;RESET TO SENT Q ADDRESS CALL GIVE ;;;GIVE BUFFER TO DMC CALL ITRY ;;;TRY TO SETUP ANOTHER BUFFER 10$: MOV (SP)+,R3 ;;;RESTORE R1,R2,R3 MOV (SP)+,R2 ;;; MOV (SP)+,R1 ;;; BR XMINTX ;;;EXIT FROM INTERRUPT 20$: BIS #UNXINT,U.ERR(R5) ;;;FLAG ERROR CONDITION BR 10$ ;EXIT AFTER POPING STACK .SBTTL COMPLETION INTERRUPT ROUTINES ;+ ; **-BUFCOM-PROCESS BUFFER COMPLETE ; ; INPUTS: ; R0=SENT Q LISTHEAD ADDRESS (U.XQ OR U.RQ) ; R1=CALLING REGISTER ; R4=CSR ADDRESS+2 ; R5=UCB ADDRESS ; 2(SP)=INTERRUPT SAVED R0 ; ; CALLING SEQUENCE: ; JSR R1,BUFCOM ; ; OUTPUTS: ; CHARACTER COUNT STORED IN X.PRM+4 OF I/O PACKET ; PACKET MOVED FROM SENT Q TO COMPLETION Q ; DMC PORT RELEASED ; ATTEMPT MADE TO SETUP ANOTHER BUFFER OF EITHER TYPE ; FORK PROCESS STARTED IF IT'S NOT RUNNING ; INTERRUPT EXITED ;- BUFCOM: MOV R2,-(SP) ;;;SAVE R2,R3 MOV R3,-(SP) ;;; DECB COUNT(R0) ;;;DECREMENT SENT COUNT CALL $QRMVF ;;;REMOVE PACKET FROM SENT Q ;;;NOTE-$QRMVF DESTROYS R2,R3 MOV 4(R4),X.PRM+4(R1);;;PUT COUNT IN I/O PACKET .IF DF M$$MGE BIC #140000,X.PRM+4(R1) ;;;CLEAR ADDRESS EXTENSION BITS .ENDC BIC #RDYO,(R4) ;;;RELEASE THE PORT MOV U.XQ(R5),R0 ;;;TRANSMIT SENT Q LISTHEAD ADDRESS CMP -(R0),-(R0) ;;;COMPLETION Q LISTHEAD ADDRESS CALL $QINSF ;;;INSERT PACKET ON COMPLETION Q ;;;NOTE-$QINSF DESTROYS R2 TST -(R4) ;;;SEL0 ADDRESS CALL ITRY ;;;TRY TO SETUP ANOTHER BUFFER MOV (SP)+,R3 ;;;RESTORE R1,R2,R3 MOV (SP)+,R2 ;;; MOV (SP)+,R1 ;;; ;;;FALL THRU TO XMFRK .SBTTL FORK PROCESSING ; ; START FORK PROCESS IF IT'S NOT RUNNING ; XMFRK: BIT #U3.FRK,U.CW3(R5);;;IS FORK PROCESS RUNNING? BNE XMINTX ;;;IF NE, YES MOV (SP)+,R0 ;;;RESTORE R0 BIS #U3.FRK,U.CW3(R5);;;INDICATE FORK PROCESS RUNNING CALL $FORK ;;;CREATE SYSTEM PROCESS ; ; FORK LEVEL PROCESSING ; MOV U.XQ(R5),R0 ;TRANSMIT SENT Q LISTHEAD ADDRESS CMP -(R0),-(R0) ;COMPLETION Q LISTHEAD ADDRESS 10$: MOV U.SCB(R5),R4 ;SCB ADDRESS MTPS S.PRI(R4) ;DISABLE INTERRUPTS CALL $QRMVF ;;;REMOVE FIRST PACKET FROM COMPLETION Q BCS 20$ ;;;IF CS, Q WAS EMPTY MTPS #0 ;;;RE-ENABLE INTERRUPTS MOV #IS.SUC&377,R2 ;STATUS WORD 1 MOV X.PRM+4(R1),R4 ;STATUS WORD 2 = BYTE COUNT CALL RAP ;RETURN THE I/O PACKET BR 10$ ;AND TRY AGAIN 20$: BIC #U3.FRK,U.CW3(R5);;;NO MORE FORK PROCESSING MTPS #0 ;;;RE-ENABLE INTERRUPTS BIT #FATAL,U.ERR(R5) ;HAS FATAL ERROR OCCURRED? BEQ EXIT ;IF EQ, NO BIT #LOST,U.ERR(R5) ;WAS IT LOST DATA? BEQ 30$ ;IF EQ, NO MOV U.RQ(R5),R0 ;RECEIVE SENT Q LISTHEAD ADDRESS MOV #IE.DAO&377,R2 ;RETURN FIRST PACKET ON SENT Q CALL DQRAP0 ;WITH A STATUS OF "IE.DAO" 30$: MOV #U3.ERR,R0 ;FATAL ERROR BIT MOV #IE.CNR&377,R2 ;ASSUME DDCMP START RECEIVED BIT #START,U.ERR(R5) ;WAS IT DDCMP START RECEIVED? BNE RQP ;IF NE, YES BIT #TIMOUT,U.ERR(R5);WAS IT TIME-OUT? BEQ RQPABO ;IF EQ, NO MOV #IE.TMO&377,R2 ;TIMEOUT ERROR CODE BR RQP ;RETURN ALL PACKETS .SBTTL TIMEOUT ;+ ; **-XMTMO-TIMEOUT ENTRY POINT ; ; INPUTS: ; R3=CONTROLLER INDEX (S.CON) ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS: ; DISCONNECT ERROR RECOVERY IS COMPLETED (QIO) ;- XMOUT: BIS #MC,@S.CSR(R4) ;MASTER CLEAR THE DEVICE CALLR XMINIT ;TIMER BLOCKED PACKETS .SBTTL CANCEL I/O AND POWERFAIL ;+ ; **-XMCANC-CANCEL I/O ENTRY POINT ; **-XMPWRF-POWERFAIL RECOVERY ENTRY POINT ; ; INPUTS: ; R0=A(I/O PACKET) CANCEL ONLY ; R1=TCB ADDRESS (CANCEL ONLY) ; R3=CONTROLLER INDEX (S.CON) ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS: ; DEVICE IS KILLED ;- XMPWF: MTPS #PR7 ;;; DISABLE INTERUPTS FROM THE WORLD MOV #U3.PWF,R0 ;;;INDICATE POWERFAIL OCCURRED BR KILL ;;; XMCAN: MOV #U3.KIL,R0 ;INDICATE I/O KILL WAS DONE ; NOTE THAT INTERRUPTS ARE NOT DISABLED FOR ; THE NEXT FOUR INSTRUCTIONS ;FALL THRU TO KILL .SBTTL KILL THE DMC ;+ ; **-KILL-KILL THE DEVICE ; **-RQP,RQPABO-ALTERNATE ENTRIES ; ; INPUTS: ; R0=KILL REASON ; R4=SCB ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS: ; R0,R1,R2,R3,R4=DESTROYED ; DMC MASTER CLEARED IF ON-LINE ; U2.ONL BIT CLEARED ; ALL PACKETS DEQUEUED AND RETURNED WITH STATUS OF "IE.ABO" ;- KILL: BIT #U2.ONL,U.CW2(R5) ;;;IS THE DEVICE ON-LINE? BNE 1$ ;;; IF NE THEN YES MTPS #0 ; ALLOW INTERRUPTS AGAIN BR EXIT ;IF EQ, NO 1$: BIS #MC,@S.CSR(R4) ;;;MASTER CLEAR THE DEVICE MTPS #0 ; ALL INTERRUPTS AGAIN RQPABO: MOV #IE.ABO&377,R2 ;STATUS WORD 2 FOR LATER RQP: BIS R0,U.CW3(R5) ;SAVE KILL REASON BIC #U2.ONL,U.CW2(R5) ;IT'S NOT ON-LINE NOW .IF DF R$$MPL!V$$RSN&Q$$22 CALL DEUMR ;DE-ASSIGN UMR'S .ENDC MOV U.XQ(R5),R0 ;TRANSMIT SENT Q LISTHEAD ADDRESS CALL 10$ ;RETURN ALL TRANSMIT PACKETS MOV U.RQ(R5),R0 ;RECEIVE SENT Q LISTHEAD ADDRESS 10$: CALL (PC) ;DO THE FOLLOWING FOR SENT Q AND WAIT Q 20$: CALL DQRAP0 ;DEQUEUE AND RETURN ONE PACKET BCC 20$ ;IF CC, Q WAS NOT EMPTY CMP (R0)+,(R0)+ ;ADVANCE TO NEXT LISTHEAD EXIT: RETURN ; ; QUEUE AN AST TO THE CCP ; .SBTTL DEQUEUE AND RETURN ONE I/O PACKET ;+ ; **-DQRAP/DQRAP0-DEQUEUE AND RETURN ONE I/O PACKET ; **-RAP-RETURN AN ALREADY DE-QUEUED I/O PACKET ; ; INPUTS: ; R0=LISTHEAD ADDRESS ; R2=I/O STATUS WORD 1 ; R4=I/O STATUS WORD 2 ; ; OUTPUTS: ; R1,R3,R4=DESTROYED ; CARRY CLEAR=PACKET DEQUEUED AND RETURNED OK ; CARRY SET=QUEUE WAS EMPTY ;- .ENABL LSB DQRAP0: CLR R4 ;ENTRY FOR STATUS WORD 2 = 0 DQRAP: MOV R2,-(SP) ;SAVE STATUS WORD 1 CALL $QRMVF ;DEQUEUE AN I/O PACKET ;NOTE-$QRMVF DESTROYS R2,R3 BCC 5$ ;IF CC, Q WAS NOT EMPTY BR 10$ ;RETURN WITH CARRY SET RAP: MOV R2,-(SP) ;SAVE STATUS WORD 1 5$: MOV R0,-(SP) ;SAVE LISTHEAD ADDRESS MOV R1,R3 ;PACKET ADDRESS MOV 2(SP),R0 ;STATUS WORD 1 MOV R4,R1 ;STATUS WORD 2 MOV U.SCB(R5),R4 ;GET SCB ADDRESS DECB S.STS(R4) ;DECR ACTIVITY COUNT CALL $IOFIN ;FINISH THE I/O PACKET ;NOTE-$IOFIN SAVES ONLY R5 CLC ;INDICATE SUCCESS MOV (SP)+,R0 ;RESTORE LISTHEAD ADDRESS 10$: MOV (SP)+,R2 ;RESTORE STATUS WORD 1 RETURN .DSABL LSB .SBTTL DE-ASSIGN UMR'S ;+ ; **-DEUMR-DEASSIGN UMR'S (FOR QIO DRIVER ONLY) ; ; INPUTS: ; R5=UCB ADDRESS ; ; OUTPUTS: ; R0,R3=DESTROYED ; R4=SCB ADDRESS ; S.MPR+2(R4)=CLEARED ;- .IF DF R$$MPL!V$$RSN&Q$$22 DEUMR: MOV R2,-(SP) ;SAVE R2 MOV R1,-(SP) ;AND R1 MOV U.SCB(R5),R4 ;GET SCB ADDRESS .IF NDF R$$MPL MOV S.MPR+2(R4),R2 ;GET UMR BLOCK ADDRESS .IFF MOV S.KRB(R4),R2 ; MOV KRB ADDRESS INTO R2 ADD K.OFF(R2),R2 ;POINT TO UMR AREA + 2 SUB #M.LGTH,R2 ;POINT TO START OF UMR AREA TST (R2) ;IS UMR ASSIGNED ? .ENDC BEQ 10$ ;IF EQ, NO UMR BLOCK (!!!) .IF NDF R$$MPL CLR S.MPR+2(R4) ;ZERO THE POINTER .IFF CLR (R2) ;ZERO THE POINTER MOV 2(R2),R2 ;R2=UMR BLOCK ADDRESS .ENDC MOV R2,R0 ;COPY UMR BLOCK ADDRESS CALL $DEUMR ;DE-ASSIGN UMR'S MOV #M.LGTH,R1 ;SETUP UMR BLOCK LENGTH CALL $DEACB ;DE-ALLOCATE UMR BLOCK 10$: MOV (SP)+,R1 ;RESTORE R1 MOV (SP)+,R2 ;AND R2 RETURN .ENDC .SBTTL TRY TO SETUP ANOTHER BUFFER FROM INTERRUPT LEVEL ;+ ; **-ITRY-TRY TO SETUP ANOTHER BUFFER FROM INTERRUPT LEVEL ; ; INPUTS: ; R4=CSR ADDRESS ; R5=UCB ADDRESS ; ; OUTPUTS: ; R0=DESTROYED ; REQUEST TYPE!IEI LEFT IN SEL0 IF EITHER WAIT Q WAS NOT EMPTY ; RECEIVE REQUESTS ARE ATTEMPTED FIRST ;- ITRY: MOV U.RQ(R5),R0 ;;;TRY RECEIVES FIRST CALL IPORT ;;;IS THE PORT AVAILABLE? BCC 10$ ;;;IF CC, YES (PORT IS LOADED) MOV U.XQ(R5),R0 ;;;THEN TRY TRANSMITS CALL IPORT ;;;IS THE PORT AVAILABLE? BCS 20$ ;;;IF CS, NO 10$: BIS #IEI,(R4) ;;;SET INTERRUPT BIT BIS #IEI,(R4) ;;;TWICE 20$: RETURN ;;; ;+ ; **-PORT-REQUEST THE DATA PORT ; **-IPORT-REQUEST THE DATA PORT FROM INTERRUPT LEVEL ; ; INPUTS: ; R0=SENT Q LISTHEAD ADDRESS (U.XQ OR U.RQ) ; R4=CSR ADDRESS ; ; OUTPUTS IF PORT WAS AVAILABLE: ; CARRY CLEAR ; REQUEST TYPE LEFT IN SEL0 ; ; OUTPUTS IF PORT WAS NOT AVAILABLE: ; CARRY SET ;- .ENABL LSB IPORT: TST 4(R0) ;;;IS WAIT Q EMPTY? BEQ 10$ ;;;IF EQ, YES - NOTHING TO DO PORT: CMPB #MAXBUF,COUNT(R0) ;;;CAN DMC ACCEPT MORE? BEQ 10$ ;;;IF EQ, NO - NO ACTION POSSIBLE ;;;NOTE-CARRY IS NOW CLEAR BIT #RDYI!RQI,(R4) ;;;IS PORT ALREADY IN USE? BNE 10$ ;;;IF NE, YES - NO ACTION POSSIBLE MOVB IOTYPE(R0),(R4) ;;;SET REQUEST TYPE AND RQI BR 20$ ;;; 10$: SEC ;;;INDICATE UNAVAILABILITY 20$: RETURN ;;; .DSABL LSB .IF DF R$$MPL ; ; ; ; CONTORLER ONLINE ENTRY POINT: ; ; ; ; THE OLRSR ROUTINE WILL ENTER THIS DRIVER AT THE XMKRB LABLE ; TO BRING THE DEVICE ONLINE OR OFFLINE. IF THE DEVICE IS ; COMMING ONLINE, THE UNIT IS MASTER CLEARED AND THE RUN BIT ; IS CLEARED. THE RUN BIT IS THEN TESTED. IF IT IS STILL SET, ; THE BS1 SWITCH IS TURNED ON WHICH MAKES IT IMPOSSIBLE TO DIABLE ; THE UNIT. THIS CONDITION IS NOT ALLOWED IN M+ AND THE ONLINE ; COMMAND WILL FAIL. IF THE DEVICE IS COMMING OFFLINE, A MASTER ; CLEAR IS ISSUED AND THE RUN BIT IS CLEARED. NO TEST IS ; NECESSARY. ; ; ; ; INPUTS: ; ; R2 = KRB ADDRESS ; R3 = CTB ADDRESS ; CARRY BIT CLEARED IF DEVICE IS TO COME ONLINE ; CARRY BIT SET IF DEVICE IS TO COME OFFLINE ; ; ; XMKRB: MOV #MC,@K.CSR(R2) ; MASTER CLEAR THE UNIT BIC #RUN,@K.CSR(R2) ; CLEAR THE RUN BIT BCS 1$ ; IF DEVICE IS COMMING OFFLINE THE RETURN BIT #RUN,@K.CSR(R2) ; ELSE TEST IF RUN BIT IS REALLY CLEARED. BEQ 1$ ; IF YES THE ALL IS WELL MOVB #IE.DNR&377,$SCERR ; ELSE THE RUN BIT BEING LOCKED ON MEANS ; THAT THE BS1 SWITCH IS ON WHICH MEANS ; THE THAT A DOWNLINE LOAD CAN NOT BE ; AVOIDED. WE DO NOT WANT THIS IN THIS ; THIS IN THE SYSTEM. 1$: RETURN ; GO BACK ; ; ; ; UNIT ONLINE - OFFLINE ENTRY POINT ; ; ; ; WHEN THE UNIT IS BROUGHT ONLINE THE OLRSR ROUTINE CALLS THE ; DRIVER AT THIS POINT WITH THE CARRY BIT CLEAR AND FOR OFFLINE ; WITH THE CARRY BIT SET. WHEN COMMING ONLINE THE UNIT IS ; SET UP USING THE DRIVER ROUTINE "SETDMC". WHEN THE UNIT IS ; OFFLINE A MASTER CLEAR IS ISSUED AND THE RUN BIT IS TURNED OFF. ; ; ; INPUTS: ; ; ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; ; OUTPUTS: ; ; ; NONE ; ; XMUCB: BCC 3$ ; IF CC, THIS ONL REQUEST 1$: MOV S.KRB(R4),R2 ; R2=KRB ADDRESS MOV #MC,@K.CSR(R2) ; MASTER CLEAR THE UNIT BIC #RUN,@K.CSR(R2) ; CLEAR THE RUN BIT 3$: RETURN ; GO BACK .ENDC .END